package org.academic.texteditor.gui.component;

import java.awt.Dimension;

import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

import org.academic.texteditor.gui.component.listener.BackgroundFocusListener;
import org.academic.texteditor.gui.component.listener.FocusKeyListener;
import org.academic.texteditor.gui.helper.DocumentManager;
import org.academic.texteditor.gui.style.Style;
import org.academic.texteditor.gui.style.StyleType;

public class ComponentFactory {

	private ComponentFactory() {

	}

	public static JLabel getLabel(String text) {
		return getLabel(text, StyleType.COMMON_LABEL);
	}

	public static JLabel getLabel(String text, StyleType styleType) {
		JLabel label = new JLabel(text);
		applyStyle(label, styleType);

		return label;
	}

	public static JTextField getFormattedTextField(MaskFormatter mask, StyleType styleType) {
		JTextField field = new JFormattedTextField(mask);
		field.addKeyListener(new FocusKeyListener());
		field.addFocusListener(new BackgroundFocusListener());
		applyStyle(field, styleType);

		return field;
	}

	public static JTextField getTextField() {
		return getTextField(StyleType.COMMON_FIELD);
	}
	
	public static JTextField getTextField(StyleType styleType) {
		JTextField field = new JTextField();
		field.addKeyListener(new FocusKeyListener());
		field.addFocusListener(new BackgroundFocusListener());
		applyStyle(field, styleType);

		return field;
	}

	public static JTextField getTextField(int length) {
		return getTextField(length, StyleType.COMMON_FIELD);
	}
	
	public static JTextField getTextField(int length, StyleType styleType) {
		JTextField field = new JTextField(length);
		field.addKeyListener(new FocusKeyListener());
		field.addFocusListener(new BackgroundFocusListener());
		applyStyle(field, styleType);

		return field;
	}

	public static JTextField getPasswordField() {
		return getPasswordField(0);
	}
	
	public static JTextField getPasswordField(int length) {
		return getPasswordField(length, StyleType.COMMON_FIELD);
	}
	
	public static JTextField getPasswordField(int length, StyleType styleType) {
		JPasswordField field = new JPasswordField(length);
		field.addKeyListener(new FocusKeyListener());
		field.addFocusListener(new BackgroundFocusListener());
		applyStyle(field, styleType);
		
		return field;
	}

	public static JScroll getTextArea(StyleType styleType) {
		JTextArea field = new JTextArea();
		field.setAutoscrolls(true);
		field.addFocusListener(new BackgroundFocusListener());
		applyStyle(field, styleType);

		JScroll scroll = new JScroll(field);
		return scroll;
	}

	public static JComboBox getComboBox() {
		return getComboBox(StyleType.COMMON_FIELD);
	}
	
	public static JComboBox getComboBox(StyleType styleType) {
		JComboBox combo = new JComboBox();
		combo.addKeyListener(new FocusKeyListener());
		combo.addFocusListener(new BackgroundFocusListener());
		applyStyle(combo, styleType);

		return combo;
	}

	public static JComboBox getComboBox(ComboBoxModel model, StyleType styleType) {
		JComboBox combo = new JComboBox(model);
		combo.addKeyListener(new FocusKeyListener());
		combo.addFocusListener(new BackgroundFocusListener());
		applyStyle(combo, styleType);

		return combo;
	}

	public static JScroll getList(StyleType styleType) {
		JList list = new JList();
		list.addFocusListener(new BackgroundFocusListener());
		applyStyle(list, styleType);

		JScroll scroll = new JScroll(list);
		return scroll;
	}

	public static JButton getButton(String action, String text) {
		return getButton(action, text, StyleType.BUTTON);
	}

	public static JButton getButton(String action, String text, StyleType styleType) {
		JButton button = new ActionButton(text);
		button.setActionCommand(action);
		if (styleType.equals(StyleType.ACTION_BUTTON)) {
			button.setPreferredSize(new Dimension(100, 35));
		} else {
			button.setPreferredSize(new Dimension(100, 25));
		}
		applyStyle(button, styleType);

		return button;
	}

	public static JScroll getPageContent() {
		PageContainer pageContainer = new PageContainer();
		DocumentManager.getInstance().addDocument(pageContainer);
		
		JScroll scroll = new JScroll(pageContainer);
		return scroll;
	}
	
	public static JScroll getGrid(String[] columns, StyleType headerStyle, StyleType gridStyle) {
		ModelGrid model = new ModelGrid(columns);
		return getGrid(model, columns, headerStyle, gridStyle);
	}

	private static JScroll getGrid(ModelGrid model, String[] columns, StyleType headerStyle, StyleType gridStyle) {
		JGrid grid = new JGrid(model);

		applyStyle(grid.getTableHeader(), headerStyle);
		applyStyle(grid, gridStyle);

		JScroll scroll = new JScroll(grid);
		return scroll;
	}

	public static void applyStyle(JComponent component, StyleType styleType) {
		Style style = styleType.getStyle();
		
		if (style == null) {
			return;
		}
		if (style.getFont() != null) {
			component.setFont(style.getFont());
		}
		if (style.getBorder() != null) {
			component.setBorder(style.getBorder());
		}
		if (style.getColor() != null) {
			component.setForeground(style.getForeground());
		}
		if (style.getBackground() != null) {
			component.setBackground(style.getBackground());
		}
		if (component instanceof JTextField) {
			JTextField textField = (JTextField) component;
			textField.setHorizontalAlignment(style.getAlignment());
		} else if (component instanceof JLabel) {
			JLabel label = (JLabel) component;
			label.setHorizontalAlignment(style.getAlignment());
		} else if (component instanceof ActionButton) {
			ActionButton button = (ActionButton) component;
			button.setPaintBackground(style.getColor());
		}
	}

}

